home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / graphics / a-g / amountains / amountains.c < prev    next >
C/C++ Source or Header  |  1996-01-14  |  10KB  |  356 lines

  1. #include <workbench/workbench.h>
  2.  
  3. #include <proto/exec.h>
  4. #include <proto/dos.h>
  5. #include <proto/icon.h>
  6.  
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <m68881.h>
  11. #include <math.h>
  12. #include <signal.h>
  13. #include <time.h>
  14.  
  15. #include "crinkle.h"
  16. #include "paint.h"
  17. #include "global.h"
  18. #include "patchlevel.h"
  19.  
  20. #define VERSION 2
  21. #define SIDE 1.0
  22.  
  23. #ifndef FALSE
  24. #define FALSE 0
  25. #endif
  26.  
  27. #ifndef TRUE
  28. #define TRUE (!FALSE)
  29. #endif
  30.  
  31. /* -------------------------------------------------------------------- */
  32. /* update strips                                                        */
  33. /* -------------------------------------------------------------------- */
  34.  
  35. Col *next_col( int paint, int reflec )
  36. {
  37.     Col    *res;
  38.     int    i, offset = 0;
  39.   
  40.     if ( paint ) {
  41.         if( reflec ) {
  42.             res = mirror( a_strip, b_strip, shadow );
  43.         }
  44.         else {
  45.             res = camera( a_strip, b_strip, shadow );
  46.         }
  47.     }
  48.     else {
  49.         res = makemap( a_strip, b_strip, shadow );
  50.     }
  51.     free( a_strip );
  52.     a_strip = b_strip;
  53.     b_strip = extract( next_strip( top ) );
  54.  
  55.     /* ---------------------------------------------------------------- */
  56.     /* update the shadows                                                */
  57.     /* shadow_slip is the Y component of the light vector.                */
  58.     /* The shadows can only step an integer number of points in the Y    */
  59.     /* direction so we maintain shadow_register as the deviation        */
  60.     /* between where the shadows are and where they should be. When the    */
  61.     /*  magnitude of this gets larger then 1 the shadows are slipped by    */
  62.     /*  the required number of points.                                    */
  63.     /* This will not work for very oblique angles so the horizontal        */
  64.     /* angle of illumination should be constrained.                        */
  65.     /* ---------------------------------------------------------------- */
  66.  
  67.     shadow_register += shadow_slip;
  68.     if ( shadow_register >= 1.0 ) {
  69.  
  70.         /* ------------------------------------------------------------ */
  71.         /* negative offset                                                */
  72.         /* ------------------------------------------------------------ */
  73.  
  74.         while ( shadow_register >= 1.0 ) {
  75.             shadow_register -= 1.0;
  76.             offset++;
  77.         }
  78.         for ( i = width - 1; i >= offset; i-- ) {
  79.             shadow[i] = shadow[i-offset] - delta_shadow;
  80.             if ( shadow[i] < b_strip[i] ) {
  81.                 shadow[i] = b_strip[i];
  82.             }
  83.  
  84.             /* -------------------------------------------------------- */
  85.             /* stop shadow at sea level                                    */
  86.             /* -------------------------------------------------------- */
  87.  
  88.             if ( shadow[i] < sealevel ) {
  89.                 shadow[i] = sealevel;
  90.             }
  91.         }
  92.  
  93.         for ( i = 0; i < offset; i++ ) {
  94.             shadow[i] = b_strip[i];
  95.  
  96.             /* -------------------------------------------------------- */
  97.             /* stop shadow at sea level                                    */
  98.             /* -------------------------------------------------------- */
  99.  
  100.             if ( shadow[i] < sealevel ) {
  101.                 shadow[i] = sealevel;
  102.             }
  103.         }
  104.     }
  105.     else if ( shadow_register <= -1.0 ) {
  106.  
  107.         /* ------------------------------------------------------------ */
  108.         /* positive offset                                                */
  109.         /* ------------------------------------------------------------ */
  110.  
  111.         while ( shadow_register <= -1.0 ) {
  112.             shadow_register += 1.0;
  113.             offset++;
  114.         }
  115.         for ( i = 0; i < width - offset; i++ ) {
  116.             shadow[i] = shadow[i+offset] - delta_shadow;
  117.             if ( shadow[i] < b_strip[i] ) {
  118.                 shadow[i] = b_strip[i];
  119.             }
  120.  
  121.             /* -------------------------------------------------------- */
  122.             /* stop shadow at sea level                                    */
  123.             /* -------------------------------------------------------- */
  124.  
  125.             if ( shadow[i] < sealevel ) {
  126.                 shadow[i] = sealevel;
  127.             }
  128.         }
  129.         for( ; i < width; i++ ) {
  130.             shadow[i] = b_strip[i];
  131.  
  132.             /* -------------------------------------------------------- */
  133.             /* stop shadow at sea level                                    */
  134.             /* -------------------------------------------------------- */
  135.  
  136.             if ( shadow[i] < sealevel ) {
  137.                 shadow[i] = sealevel;
  138.             }
  139.         }
  140.     }
  141.     else {
  142.  
  143.         /* ------------------------------------------------------------ */
  144.         /* no offset                                                    */
  145.         /* ------------------------------------------------------------ */
  146.  
  147.         for ( i = 0; i < width; i++ ) {
  148.             shadow[i] -= delta_shadow;
  149.             if ( shadow[i] < b_strip[i] ) {
  150.                 shadow[i] = b_strip[i];
  151.             }
  152.  
  153.             /* -------------------------------------------------------- */
  154.             /* stop shadow at sea level                                    */
  155.             /* -------------------------------------------------------- */
  156.  
  157.             if ( shadow[i] < sealevel ) {
  158.                 shadow[i] = sealevel;
  159.             }
  160.         }
  161.     }
  162.     return res;
  163. }
  164.  
  165. void init_graphics( int, int *, int *, int, Gun *, Gun *, Gun *, char *, ULONG, char * );
  166. void finish_graphics( void );
  167. void plot_pixel(int, int, unsigned char );
  168. void scroll_screen( int );
  169. void zap_events( int );
  170. void finish_prog( int );
  171.  
  172. int        s_height,
  173.         s_width,
  174.         mapwid;
  175.  
  176. void plot_column( int p, int map, int reflec, int snooze )
  177. {
  178.     Col    *l;
  179.     int    j;
  180.   
  181.     l = next_col( 1 - map, reflec ); 
  182.     if ( map ) {
  183.         for ( j = 0; j < s_height - mapwid; j++ ) {
  184.             plot_pixel( p, s_height - 1 - j, BLACK );
  185.         }
  186.         for ( j = 0; j < mapwid; j++ ) {
  187.             plot_pixel( p, mapwid - 1 - j, l[j] );
  188.         }
  189.     }
  190.     else {
  191.         for ( j = 0; j < height; j++ ) {
  192.  
  193.             /* -------------------------------------------------------- */
  194.             /* we assume that the scroll routine fills the new region    */
  195.             /* with a SKY value. This allows us to use a textured sky    */
  196.             /* for B/W displays                                            */
  197.             /* -------------------------------------------------------- */
  198.  
  199.             if ( l[j] != SKY ) {
  200.                 plot_pixel( p, s_height - 1 - j, l[j] );
  201.             }
  202.         }
  203.     }
  204.     free( l );
  205.     zap_events( snooze );
  206. }
  207.  
  208. extern LONG activepri, inactivepri;
  209.  
  210. static char *pubscreen, *displaymode;
  211. static ULONG depth;
  212.  
  213. static int imin( int a, int b )
  214. {
  215.     return min( a, b );
  216. }
  217.  
  218. static int imax( int a, int b )
  219. {
  220.     return max( a, b );
  221. }
  222.  
  223. static double fmin( double a, double b )
  224. {
  225.     return min( a, b );
  226. }
  227.  
  228. static double fmax( double a, double b )
  229. {
  230.     return max( a, b );
  231. }
  232.  
  233. void main( int argc, char **argv )
  234. {
  235.     int        i, p;
  236.     int        repeat;
  237.     int        map;
  238.     int        reflec;
  239.     int        root;
  240.  
  241.     Gun        *clut[3];
  242.     UBYTE    **a;
  243.  
  244.     /* ---------------------------------------------------------------- */
  245.     /* handle command line/tool type arguents                            */
  246.     /* ---------------------------------------------------------------- */
  247.  
  248.  
  249.     if ( a = ArgArrayInit( argc, argv ) ) {
  250.         root        = ArgString( a, "BACKDROP", NULL ) != NULL;
  251.         s_width        = imax( 40, ArgInt( a, "WIDTH", 320 ) );
  252.         s_height    = imax( 40, ArgInt( a, "HEIGHT", 240 ) );
  253.         pubscreen    = ArgString( a, "PUBSCREEN", "Workbench" );
  254.         displaymode    = ArgString( a, "DISPLAYMODE", NULL );
  255.         depth        = imax( 0, ArgInt( a, "DEPTH", 0 ) );
  256.         map            = ArgString( a, "MAP", NULL ) != NULL;
  257.         reflec        = ArgString( a, "REFLECTIONS", NULL ) != NULL;
  258.         repeat        = imax( 2, ArgInt( a, "SCROLLCOLUMNS", 20 ) );
  259.         band_size    = imax( 2, ArgInt( a, "BANDSIZE", BAND_SIZE ) );
  260.         n_col        = BAND_BASE + N_BANDS * band_size;
  261.         n_col        = imax( MIN_COL, ArgInt( a, "COLOURS", n_col ) );
  262.         band_size    = ( n_col - BAND_BASE ) / N_BANDS;
  263.         n_col        = BAND_BASE + N_BANDS * band_size;
  264.         snooze_time    = imax( 0, ArgInt( a, "SLEEP", 0 ) );
  265.         phi            = PI * atof( ArgString( a, "VLIGHTANGLE", "40.0" ) ) / 180.0;
  266.         phi            = fmax( 0.0, fmin( PID2, phi ) );
  267.         alpha        = PI * atof( ArgString( a, "HLIGHTANGLE", "0.0" ) ) / 180.0;
  268.         alpha        = fmax( -PI / 3.0, fmin( PI / 3.0, alpha ) );
  269.         stretch        = atof( ArgString( a, "VSTRETCH", "0.6" ) );
  270.         shift        = atof( ArgString( a, "VSHIFT", "0.5" ) );
  271.         sealevel    = atof( ArgString( a, "SEALEVEL", "0.0" ) );
  272.         slope        = imax( 2, ArgInt( a, "SLOPE", 2 ) );
  273.         forceheight    = atof( ArgString( a, "FORCEHEIGHT", "-1.0" ) );
  274.         contour        = atof( ArgString( a, "CONTOUR", "0.3" ) );
  275.         altitude    = atof( ArgString( a, "ALTITUDE", "2.5" ) );
  276.         distance    = atof( ArgString( a, "DISTANCE", "4.0" ) );
  277.         contrast    = fmax( 0.0, atof( ArgString( a, "CONTRAST", "1.0" ) ) );
  278.         ambient        = fmax( 0.0, fmin( 1.0, atof( ArgString( a, "AMBIENT", "0.3" ) ) ) );
  279.         vfract        = fmax( 0.0, atof( ArgString( a, "VFRACT", "0.6" ) ) );
  280.         fdim        = fmax( 0.5, fmin( 1.0, atof( ArgString( a, "FDIM", "0.65" ) ) ) );
  281.         seed        = ArgInt( a, "SEED", 0 );
  282.         levels        = imax( 2, ArgInt( a, "LEVELS", 10 ) );
  283.         cross        = ArgString( a, "CROSS", NULL ) != NULL;
  284.         smooth        = ArgInt( a, "SMOOTH", 1 );
  285.         mix            = atof( ArgString( a, "MIX", "0.0" ) );
  286.         midmix        = atof( ArgString( a, "MIDMIX", "0.0" ) );
  287.         stop        = imax( 0, ArgInt( a, "STOP", 2 ) );
  288.         activepri    = ArgInt( a, "ACTIVEPRI", 0 );
  289.         inactivepri    = ArgInt( a, "INACTIVEPRI", -25 );
  290.  
  291.         if ( repeat & 1 ) repeat++;
  292.  
  293.     }
  294.     else {
  295.         PutStr( "Error: Cannot allocate argument array!\n" );
  296.         exit( 5 );
  297.     }
  298.  
  299.     for ( i = 0; i < 3; i++ ) {
  300.         clut[i] = (Gun *) malloc( n_col * sizeof(Gun) );
  301.         if( ! clut[i] ) {
  302.             PutStr( "malloc failed for clut\n" );
  303.             exit( 1 );
  304.         }
  305.     }
  306.     set_clut( n_col, clut[0], clut[1], clut[2] );
  307.     init_graphics( root, &s_width, &s_height, n_col, clut[0], clut[1], clut[2], displaymode, depth, pubscreen );
  308.     for ( i = 0; i < 3; i++ ) {
  309.         free( clut[i] );
  310.     }
  311.  
  312.     height = s_height;
  313.     
  314.     srand48( seed ? seed : time( NULL ) );
  315.  
  316.     init_artist_variables();
  317.  
  318.     if ( s_height > width ) {
  319.         mapwid = width;
  320.     }
  321.     else {
  322.         mapwid = s_height;
  323.     }
  324.     if ( repeat > 0 ) {
  325.         for ( p = 0; p < s_width; p++ ) {
  326.             plot_column( p, map, reflec, 0 );
  327.         }
  328.     }
  329.     else {
  330.         for ( p = s_width - 1; p >= 0; p-- ) {
  331.             plot_column( p, map, reflec, 0 );
  332.         }
  333.     }
  334.     while ( TRUE ) {
  335.  
  336.         /* ------------------------------------------------------------ */
  337.         /* do the scroll                                                */
  338.         /* ------------------------------------------------------------ */
  339.  
  340.         scroll_screen( repeat );
  341.         if( repeat > 0) {
  342.             for ( p = s_width - repeat; p < s_width - 1; p++ ) {
  343.                 plot_column( p, map, reflec, 0 );
  344.             }
  345.         }
  346.         else {
  347.             for ( p = -1 - repeat; p >= 0; p-- ) {
  348.                 plot_column( p, map, reflec, 0 );
  349.             }
  350.         }
  351.         plot_column( p, map, reflec, snooze_time );
  352.     }
  353.  
  354.     ArgArrayDone();
  355. }
  356.